// Copyright (c) 2008 Matthew Johnson
// Licensed under the MIT License (see license.txt)
package actionml.display {
	import actionml.Global;
	import actionml.events.GeometryEvent;
	import actionml.geom.RectangleAccessorMethods;
	
	import flash.display.DisplayObject;
	import flash.display.Stage;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	public class DisplayObjectAccessorMethods {
		public static function initialize() {
			Global.initializeExtension(RectangleAccessorMethods, Rectangle);
			Global.initializeExtension(DisplayObjectAccessorMethods, DisplayObject);
		}
		public static var instanceMethods:Object = {
			getPosition: function() {
				if (this is Stage) {
					return (new Point(0, 0));
				}
				return new Point(this.x, this.y);
			},
			getAspectRatio: function() {
				return this.width / this.height;
			},
			getRectAspectRatio: function() {
				var r:Rectangle = this.getRect(this.parent);
				return r.width / r.height;
			},
			getPositionInCoordinateSpaceOfObject: function(o:DisplayObject) {
				return o.globalToLocal(this.parent.localToGlobal(this.getPosition()));
			},
			setX: function(x:Number, dispatch:Boolean=true) {
				this.x = x;
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;				
			},
			setY: function(y:Number, dispatch:Boolean=true) {
				this.y = y;
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;				
			},
			setPosition: function(x:Number, y:Number, dispatch:Boolean=true) {
				this.x = x;
				this.y = y;
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setPositionPoint: function(p:Point, dispatch:Boolean=true) {
				this.x = p.x;
				this.y = p.y;
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			move: function(p:Point, dispatch:Boolean=true) {
				this.x += p.x;
				this.y += p.y;
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setCenterX: function(x:Number, dispatch:Boolean=true) {
				this.x = x - (this.getBounds(this.parent).getCenterX() - this.x);
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setCenterY: function(y:Number, dispatch:Boolean=true) {
				this.y = y - (this.getBounds(this.parent).getCenterY() - this.y);				
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setCenter: function(x:Number, y:Number, dispatch:Boolean=true) {
				this.setCenterX(x, false);
				this.setCenterY(y, false);
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setCenterPoint: function(p:Point, dispatch:Boolean=true) {
				this.setCenterX(p.x, false);
				this.setCenterY(p.y, false);
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},	
			setLeft: function(l:Number, dispatch:Boolean=true) {
				this.x = l + (this.x - this.getBounds(this.parent).getLeft());
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setRight: function(r:Number, dispatch:Boolean=true) {
				this.x = r - (this.getBounds(this.parent).getRight() - this.x); 	
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setTop: function(t:Number, dispatch:Boolean=true) {
				this.y = t + (this.y - this.getBounds(this.parent).getTop()); 
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setBottom: function(b:Number, dispatch:Boolean=true) {
				this.y = b - (this.getBounds(this.parent).getBottom() - this.y); 	
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setTopLeft: function(t:Number, l:Number, dispatch:Boolean=true) {
				this.setTop(t, false);
				this.setLeft(l, false);
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setTopLeftPoint: function(p:Point, dispatch:Boolean=true) {
				this.setTop(p.y, false);
				this.setLeft(p.x, false);
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setTopRight: function(t:Number, r:Number, dispatch:Boolean=true) {
				this.setTop(t, false);
				this.setRight(r, false);
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setTopRightPoint: function(p:Point, dispatch:Boolean=true) {
				this.setTop(p.y, false);
				this.setRight(p.x, false);
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setBottomLeft: function(b:Number, l:Number, dispatch:Boolean=true) {
				this.setBottom(b, false);
				this.setLeft(l, false);
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setBottomLeftPoint: function(p:Point, dispatch:Boolean=true) {
				this.setBottom(p.y, false);
				this.setLeft(p.x, false);
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setBottomRight: function(b:Number, r:Number, dispatch:Boolean=true) {
				this.setBottom(b, false);
				this.setRight(r, false);
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setBottomRightPoint: function(p:Point, dispatch:Boolean=true) {
				this.setBottom(p.y, false);
				this.setRight(p.x, false);
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setWidth: function(w:Number, dispatch:Boolean=true) {
				this.width = w;
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.RESIZE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setHeight: function(h:Number, dispatch:Boolean=true) {
				this.height = h;
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.RESIZE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setSize: function(p:Point, dispatch:Boolean=true) {
				this.width = p.x;
				this.height = p.y;
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.RESIZE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			},
			setBounds: function(b:Rectangle, dispatch:Boolean=true) {
				this.setTopLeft(b.getTopLeft(), false);
				this.setSize(b.getSize(), false)
				if (dispatch) {
					this.dispatchEvent(new GeometryEvent(GeometryEvent.MOVE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.RESIZE));
					this.dispatchEvent(new GeometryEvent(GeometryEvent.BOUNDS_CHANGE));
				}
				return this;
			}
		};
	}
}